using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Ccr.Core;
using System.Threading;
using System.Configuration;

namespace mds.Queue
{
	/// <summary>
	/// This class is a used behinds the scenes to create Dispatchers for in-memory queues.
	/// It also provides a default Dispatcher so multiple queue processors can share a single
	/// Dispatcher.
	/// 
	/// If the AppSetting "DefaultDispatcherThreadCount" is set, it will instantiate the Dispatcher
	/// with the number of threads specified, otherwise it'll use the Dispatcher default constructor.
	/// <see>Microsoft.Ccr.Core.Dispatcher</see>
	/// </summary>
	internal static class DispatcherFactory
	{
		private static object syncRoot = new object();
		private static Dispatcher defaultDispatcher;
		private static DispatcherQueue queue;	// this is necessary to work around a CCR bug

		public static Dispatcher DefaultDispatcher
		{
			get 
			{
				lock (syncRoot)
				{
					if (defaultDispatcher == null)
					{
						int threadCount=0;

						//int.TryParse(Beisen.Configuration.ConfigManager.AppSettings["DefaultDispatcherThreadCount"], out threadCount);

						if (threadCount == 0)
						{
							defaultDispatcher = new Dispatcher();	// A Dispatcher instantiated this way creates a thread for every processor on the machine
						}
						else
						{
							//defaultDispatcher = new Dispatcher(threadCount, "Default Dispatcher");

                            defaultDispatcher = new Dispatcher(threadCount, ThreadPriority.Highest, true, "Default Dispatcher");
						}
					}
				}

				return defaultDispatcher; 
			}
		}

		static DispatcherFactory()
		{
		}

		/// <summary>
		/// This will kill the default dispatcher for the ENTIRE AppDomain.  Only
		/// do this if you're sure you're queue is the only one using the default dispatcher.
		/// </summary>
		public static void DestroyDefaultDispatcher()
		{
			for (int i = 0; i < defaultDispatcher.DispatcherQueues.Count; i++)
				defaultDispatcher.DispatcherQueues[i].Dispose();

			defaultDispatcher.Dispose();
			defaultDispatcher = null;
		}

		public static Dispatcher CreateDispatcher(int threadCount, ThreadPriority priority, string threadPoolName)
		{
			return new Dispatcher(threadCount, priority, true, threadPoolName);
		}

		public static Dispatcher CreateDispatcher(int threadCount, string threadPoolName)
		{
			return new Dispatcher(threadCount, threadPoolName);
		}

		public static Dispatcher CreateDispatcher()
		{
			return new Dispatcher();
		}
	}
}
